package 进阶阶段;

public class demo13异常 {
    public static void main(String[] args) throws Exception{
        //异常 ：指的是程序在执行( 编译和运行)过程中，出现的非正常的情况，最终会导致JVM的非正常停止(中断)。
        //在Java等面向对象的编程语言中，异常本身是一个类(模拟一类事物)，产生异常就是创建异常对象并抛出了一个异常对象。
        //Java虚拟机默认处理异常的方式是中断处理,把程序中断,停止,并告诉你异常问题的名字,原因,代码位置

        //异常的根类是Throwable
        //其下有两个子类：Error与Exception，平常所说的异常指Exception。
        //Error错误：不能处理，只能尽量避免
        //Exception异常：由于使用不当导致，可以避免的，由程序员去处理

        //异常(Exception)的分类：
            //编译时期异常:checked异常。在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)
            //运行时期异常:runtime异常。在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错)。(如数学异常)

        yiChang("确定");

        method();

        //ArithmeticException：算术异常，字母不能为0
        System.out.println(10/0);
        Throwable throwable = new Throwable();
        throwable.printStackTrace();

    }

    //一直递归，导致报错
    //StackOverflowError：栈内存溢出错误
    public static void method(){
        System.out.println("method");
        method();
    }

    //throw关键字，它用来抛出一个指定的异常对象
    //throws声明一个异常类型出去,继续交个方法的调用去处理
        //两者最终交给java虚拟机处理中断中止程序，所以throws的处理跟java虚拟机的默认处理一样，后续代码不再执行
    //try catch：自己处理，没有交给java虚拟机，后续代码继续执行
    //finally代码块：跟try catch组合使用，不能单独使用
        //里面的代码永远都会执行，除非你在它之前退出java虚拟机
        //使用‘System.exit(0);’程序立马停止，后面的代码不走了
        //如果finally代码块中有return语句，永远返回finally中的结果，我们要避免这种情况

    public static void yiChang(String b) throws Exception{
        if ("确定".equals(b)){
            try{
                System.out.println(10/0);
            }catch(Exception  e){//e=对象;//如果上面出现问题,立马catch块抓住它,进行捕获
                //Throwable中的常用方法：
                //printStackTrace():打印异常的详细信息。
                //getMessage():获取发生异常的原因。
                //toString():获取异常的类型和异常描述信息(手动写一般不用)。
                System.out.println("出现异常了，我把异常打印出来");
                e.printStackTrace();//把异常打印出来，代码继续执行
                System.out.println("--");
                System.out.println(e.getMessage());//异常的原因
                System.out.println("-------");
                System.out.println(e.toString());//异常的类型和异常描述信息
                System.out.println("-------------");
//                throw new Exception("自己抛出异常，后面的代码就不执行");
            }finally {
//                System.exit(0);//正常推出虚拟机
                System.out.println("最终代码块，必须要执行的代码");
            }

            System.out.println("继续执行下面的代码");
            throw new CustomException("直接抛出异常");
        }
    }

    //异常注意事项
        //运行时异常被抛出(throw异常对象)可以不处理。即不捕获(trycatch)也不声明(throws)抛出。
        //如果父类抛出了多个异常,子类覆盖父类方法时,只能抛出相同的异常或者是他的子集。
        //父类方法没有抛出异常，子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常，只能捕获处理，不能声明抛出
        //当多异常处理时，捕获处理，前边的类不能是后边类的父类
        //在try/catch后可以追加finally代码块，其中的代码一定会被执行，通常用于资源回收(一定要做事情)。
        //如果finally有return语句,永远返回finally中的结果,避免该情况. //

}

//自定义异常，使用CustomException自定义的异常报错
class CustomException extends Exception{

    public CustomException(String message) {
        super(message);
    }

}
